package oralExamSchedulingSystem;

import java.sql.Time;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Set;
import java.util.TreeSet;

import oralExamSchedulingSystem.Timetable;


public class Scheduler {

	private ArrayList<Student> _studentList;
	private String _startTime;
	private String _duration;
	private int _group;
	private String _roomNum;
	private int _minGroupSize;
	private int _normalGroupSize;
	private HashMap<String,LinkedList<Student> > listWithClassNameAndStudent;
	
	
	public Scheduler() {
		_studentList = new ArrayList<Student>(); 
		this._startTime = null;
		this._duration = null;
		this._group = 0;
		this._roomNum = null;
		this._minGroupSize = 0;
		this._normalGroupSize = 0;
	}
	private int countStudent() {
		return _studentList.size();
	}

//	private LinkedList<Student> getPartOfStudentFromClass(String className, int numberOfStudent, char sex) {
//		LinkedList test = new LinkedList();
//		return test;
//	}
//
//	private void assignStudentListToTimeSlot(Timetable timetable, int timeSlot, ArrayList <Student> studentList) {
//		
//	}

	private HashMap<String,LinkedList<Student> > separateStudentFromClass(ArrayList <Student> studentList) {
		//	Receive all students as ArrayList from io
		HashMap<String,LinkedList<Student> > listWithClassNameAndStudent=new HashMap<String,LinkedList<Student> >();
		Iterator <Student> studentItr = studentList.iterator();
		while (studentItr.hasNext()) {
			Student s = studentItr.next();
			String classNameOfStudent = s.getClassName();
			Set<String> classSet = listWithClassNameAndStudent.keySet();
			Iterator<String> iter=classSet.iterator();
			boolean classExisted=false;
			while(iter.hasNext()){
				String className=iter.next();
				if(className.equals(classNameOfStudent))
					classExisted=true;
			}
			if(!classExisted){
				LinkedList<Student> specificClassName = new LinkedList<Student>();
				specificClassName.add(s);
				listWithClassNameAndStudent.put(classNameOfStudent, specificClassName);
			}else{
				LinkedList<Student> specificClassName = listWithClassNameAndStudent.get(classNameOfStudent);
				specificClassName.add(s);
			}
		}
		return listWithClassNameAndStudent;
	}
	
	public String schedule(Timetable timetable, ArrayList <Student> studentList, int _normalGroupSize, int NumberOfgroup, LinkedList<String> roomNum) {
		HashMap<String,LinkedList<Student> > listWithClassNameAndStudent=separateStudentFromClass(studentList);
		// Pseudo-Randomly select one class name to eliminate
		HashMap<String,LinkedList<Student> > pickedClass=new HashMap<String,LinkedList<Student> >();
		
		//hard code to get 3class first
		pickedClass.put("5A",listWithClassNameAndStudent.get("5A"));
		pickedClass.put("5B",listWithClassNameAndStudent.get("5B"));
		pickedClass.put("5C",listWithClassNameAndStudent.get("5C"));
		pickedClass.put("5D",listWithClassNameAndStudent.get("5D"));
		
		Set<String> classNameSet=pickedClass.keySet(); //get a set of class name, eg {"5C" , "5A" , "5B"}
		TreeSet<String> orderedClassNameSet=new TreeSet<String>();	// Automatically in order
		Iterator<String> classNameSet_iter=classNameSet.iterator();
		while(classNameSet_iter.hasNext()){
			orderedClassNameSet.add(classNameSet_iter.next()); //insert unordered Set of String to ordered Treeset so that the result will be,eg {"5A" , "5B" , "5C"} 
		}
		
		//after this line, the orderedClassNameSet will be {"5A" , "5B" , "5C"}, So use this set to getback the iterator of LinkedList<Student> from
		
		LinkedList<Iterator> class_iter=new LinkedList<Iterator>(); //to store the lterator
		Iterator<String> ClassName_iter=orderedClassNameSet.iterator(); //to get the iterator to loop back the Set of String "5A","5B","5C"
		
		while(ClassName_iter.hasNext()){
			String className=ClassName_iter.next(); //get back the String of the specific class,eg "5A"
			LinkedList<Student> specificClass=pickedClass.get(className); //get back the specific class by using the string "5A" eg, 5A class LinkedList<Student>
			Iterator<Student> specificClassIterator = specificClass.iterator(); //get back the iterator of a class
			class_iter.add(specificClassIterator); //insert the iterator into a LinkedList of iterator
		}
		
		ArrayList<ArrayList<Group> > subjectTimeTable=timetable.getSchedule(); //get back the TimeTable
		
		
		Iterator<Iterator> iteratorOfclass_iter=class_iter.iterator(); //get the interator that return the specificClassIterator
		
		while(iteratorOfclass_iter.hasNext()){
			Iterator<Student> specificClassIterator=iteratorOfclass_iter.next(); //get back the specific class iterator
			int groupCount=0;
			while(specificClassIterator.hasNext() && groupCount<timetable.getNumberOfGroup()){ //to insert student to group, next 2 constraint, (1) the class must have students (2) the number of student is less than or equal to number of group, if it is bigger than the number of group, then the remaining student will not be added to group 
				Student student=specificClassIterator.next(); //get A student from the class
				Group group=timetable.getGroupByID(groupCount); //get the group
				group.addStudent(student); //insert student into a group
				groupCount++;
			}
		}
		
		//from now, get the remaining student from all the class
		LinkedList<Student> bufferedStudentList=new LinkedList<Student>();
		
		iteratorOfclass_iter=class_iter.iterator(); //reset the iterator that store the specificClassIterator
		while(iteratorOfclass_iter.hasNext()){
			Iterator<Student> specificClassIterator=iteratorOfclass_iter.next(); //get back the specific class iterator
			while(specificClassIterator.hasNext()){
				Student remainingStudent=specificClassIterator.next();
				bufferedStudentList.add(remainingStudent);
			}		
		}
		
		LinkedList<Student> remainingClassFromBeginning=listWithClassNameAndStudent.get("5E");
		Iterator<Student> remaingingClass_iter=remainingClassFromBeginning.iterator();
		while(remaingingClass_iter.hasNext()){
			Student studentFromRemainingClass=remaingingClass_iter.next();
			bufferedStudentList.add(studentFromRemainingClass);
		}
		
		System.out.println(subjectTimeTable);
		System.out.println(bufferedStudentList);
		return subjectTimeTable.toString()+bufferedStudentList;
		// Debug
//		_normalGroupSize = 4;
//		_group = 7;
//		// Debug
//		
//		
//		
//		//	Find out partialStudentList
//		Iterator <Student> studentItr = studentList.iterator();
//		
//		HashMap<String,String> hMap = new HashMap<String, String>();
//		
//		
//		
//		while (studentItr.hasNext()) {
//			Student s = studentItr.next();
//			
//			
//		}
//		
//		
//		
//		int numberOfTimeslot = countStudent()/(_normalGroupSize*_group);
//		
//		for (int i = 0 ; i < numberOfTimeslot; i++) {
//			//assignStudentListToTimeSlot(timetable, 1, partialStudentList);
//		}
//			
//		
	}
}

// public void schedule(Timetable Timetable, Student Student[]) {
//
//
// Date d1 = null;
// java.text.SimpleDateFormat simple1 = new java.text.SimpleDateFormat();
//
//
// try {
// simple1.applyPattern("HHmmss");
// d1 = simple1.parse("131313");
// } catch (Exception e) {
//
// }
//
// Group g1 = new Group(5, 1, d1, "Chinese", 5);
//
// int time = 5;
// int roomNum = g1.getRoomNum();
//
// java.util.Date date;
// java.text.SimpleDateFormat simple = new java.text.SimpleDateFormat();
// // simple.applyPattern("yyyy-MM-dd");
// try {
// /*
// * date = simple.parse("2011-1-1");
// * System.out.println(date.toString());
// */
// simple.applyPattern("HHmmss");
// date = simple.parse("131313");
// Timetable.setDate(date);
//
// System.out.println(date.toString());
// /*
// * simple.applyPattern("yyyy-MM-dd HHmmss"); date =
// * simple.parse("2011-1-1 131313");
// * System.out.println(date.toString());
// */
//
// System.out.println(new java.text.SimpleDateFormat().format(date));
// System.out.println(new java.text.SimpleDateFormat("HHmmss")
// .format(date));
// } catch (Exception e) {
//
// }
//
// Timetable.setSchedule(5, 5, g1);
// Timetable.getSchedule(time, roomNum);
//
// }

